package com.frontalcode 
{
	/**                  
     * The ContainerMgrEvent class describes events related to the <manager />
	 * tag.
     */
    public class ContainerMgrEvent extends FrontalEvent
    {
		// When a transition commences and there is already a next child, i.e.,
		// there is already a transaction in process then we dispatch 
		// WILL_SELECT. (Note that this is not a guarantee as we only queue up 
		// at most one container for after the current transition completes.)
		// If there is no transition in progress, SELECT is dispatched. Also, 
		// PROGRESS is dispatched with a progress of 0.
		//
		// Note that there is no DESELECT event. That is because in the SELECT 
		// event, the current Container is the one being deselected.
		//
		// When the transition completes (even if it is in same frame as when it
		// started) PROGRESS is dispatched with a progress of 1. Also,
		// TRANSITION_END is dispatched.
		//
		// If the transition is paused, we dispatch PAUSE and if it is
		// resumed, we send RESUME.
		//
		// If the manager is in autoplay mode then HOLD_PROGRESS is dispatched
		// each frame that it is holding. It is guaranteed that there will
		// always be a such an event with a progress of 0 and one with a
		// progress of 1 if there are any.
		//
		
		/**
		 * @private
		 */
		static public var WILL_SELECT				: String = "willSelect";

		/**
		 * @private
		 */
		static public var SELECT					: String = "select";

		/**
		 * @private
		 */
		static public var PROGRESS					: String = "progress";

		/**
		 * @private
		 */
		static public var TRANSITION_END			: String = "transitionEnd";

		/**
		 * @private
		 */
		static public var PAUSE					: String = "pause";

		/**
		 * @private
		 */
		static public var RESUME					: String = "resume";

		/**
		 * @private
		 */
		static public var HOLD_PROGRESS			: String = "holdProgress";


		/**
		 * @private
		 */
		public var manager : ContainerManager;

		/**
		 * @private
		 */
		public var current : Container;

		/**
		 * @private
		 */
		public var next : Container;

		/**
		 * @private
		 */
		public var afterNext : Container;

		/**
		 * @private
		 */
		public var progress : Number;

		/**
		 * @private
		 */
		public var transitioners : Array;

		/**
		 * Creates a new ContainerMgrEvent instance.
		 */
		function ContainerMgrEvent ( type : String, manager : ContainerManager, progress : Number = 0, doNotDispatchContainerEvents : Boolean = false )
		{
			super ( type );
			
			this.manager		= manager;
			current				= manager.current;
			next				= manager.next;
			afterNext			= manager.afterNext;
			transitioners		= manager.transitioners;
			this.progress		= progress;
			
			if ( ! doNotDispatchContainerEvents ) dispatchContainerEvents ( );
		}
		
		/*
			Function: dispatchContainerEvents
			
				Manager events may also generate events on the containers.
		*/
		/**
		 * @private
		 */
		internal function dispatchContainerEvents ( ) : void
		{
			if ( type == WILL_SELECT )
			{
				if ( afterNext != null ) afterNext.dispatchEvent ( new FrontalEvent ( FrontalEvent.WILL_SELECT ) );
			}
			else if ( type == SELECT )
			{
				if ( current != null ) current.dispatchEvent ( new FrontalEvent ( FrontalEvent.DESELECT ) );
				if ( next != null ) next.dispatchEvent ( new FrontalEvent ( FrontalEvent.SELECT ) );
			}
			else if ( type == TRANSITION_END )
			{
				if ( current != null ) current.dispatchEvent ( new FrontalEvent ( FrontalEvent.DESELECT_TRANSITION_END ) );
				if ( next != null ) next.dispatchEvent ( new FrontalEvent ( FrontalEvent.SELECT_TRANSITION_END ) );
			}
			
			// Also handle the "reset-on-*" styles. We only dispatch at most one
			// reset event for each element for each manager event.
			//
			for each ( var element : DocumentElement in [ current, next, afterNext ] )
			{
				if ( element == null ) continue;
				
				if ( 
						( element.getStyle ( "reset-on-select"                  ) && type == SELECT         && element === next      ) ||
						( element.getStyle ( "reset-on-deselect"                ) && type == SELECT         && element === current   ) ||
						( element.getStyle ( "reset-on-select-transition-end"   ) && type == TRANSITION_END && element === next      ) ||
						( element.getStyle ( "reset-on-deselect-transition-end" ) && type == TRANSITION_END && element === current   ) ||
						( element.getStyle ( "reset-on-will-select"             ) && type == WILL_SELECT    && element === afterNext )
					)
				{
					element.dispatchEvent ( new FrontalEvent ( FrontalEvent.RESET ) );
				}
			}
		}
	}
}

